package org.example.cmsvue.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.example.cmsvue.entity.Menus;
import org.example.cmsvue.entity.RoleMenus;
import org.example.cmsvue.mapper.MenusMapper;
import org.example.cmsvue.service.IMenusService;
import org.example.cmsvue.service.IRoleMenusService;
import org.example.cmsvue.vo.MenuVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author laifeng
 * @since 2025-02-19
 */
@Service
@AllArgsConstructor
public class MenusServiceImpl extends ServiceImpl<MenusMapper, Menus> implements IMenusService {
    private final IRoleMenusService roleMenusService;

    public List<MenuVO> getMenuTreeByRoleId(Integer roleId) {
        // 1. 获取角色关联的菜单ID列表
        List<Integer> menuIds = roleMenusService.list(new QueryWrapper<RoleMenus>()
                        .eq("role_id", roleId))
                .stream()
                .map(RoleMenus::getMenuId)
                .collect(Collectors.toList());

        if (menuIds.isEmpty()) {
            return Collections.emptyList();
        }

        // 2. 查询所有关联的菜单
        List<Menus> menus = listByIds(menuIds);

        // 3. 转换为VO对象并构建树结构
        List<MenuVO> menuVOS = menus.stream().map(menu -> {
            MenuVO vo = new MenuVO();
            BeanUtils.copyProperties(menu, vo);
            return vo;
        }).collect(Collectors.toList());

        return buildTree(menuVOS);
    }

    private List<MenuVO> buildTree(List<MenuVO> nodes) {
        Map<Integer, MenuVO> nodeMap = new HashMap<>();
        List<MenuVO> roots = new ArrayList<>();

        // 创建节点映射
        for (MenuVO node : nodes) {
            nodeMap.put(node.getId(), node);
        }

        // 构建树结构
        for (MenuVO node : nodes) {
            Integer parentId = node.getParentId();
            if (parentId == null || parentId == 0) {
                roots.add(node);
            } else {
                MenuVO parent = nodeMap.get(parentId);
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(node);
                }
            }
        }

        // 排序（按sort字段）
        roots.sort(Comparator.comparingInt(MenuVO::getSort));
        for (MenuVO root : roots) {
            if (root.getChildren() != null) {
                root.getChildren().sort(Comparator.comparingInt(MenuVO::getSort));
            }
        }

        return roots;
    }
}
